package net.javastone.toolkit.core.utils;

import com.fasterxml.jackson.databind.JsonNode;
import lombok.experimental.UtilityClass;
import net.javastone.toolkit.core.model.CompareResult;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * Created by sdliang on 2019/4/10.
 */
@UtilityClass
public class Compare {

  /**
   * 对比两个json, 找出不一样的字段
   *
   * @param source 源
   * @param target 目标
   * @return
   */
  public static CompareResult compareJson(String source, String target) throws IOException {
    return compareJson(Jsons.of(source).toTree(), Jsons.of(target).toTree());
  }

  /**
   * 对比两个json, 找出不一样的字段
   *
   * @param source 源
   * @param target 目标
   * @return
   */
  public static CompareResult compareJson(JsonNode source, JsonNode target) throws IOException {
    //初始化
    CompareResult result = new CompareResult();
    result.setFromProps(new CopyOnWriteArraySet<>());
    result.setToProps(new CopyOnWriteArraySet<>());
    result.setValueDiffs(new CopyOnWriteArraySet<>());
    //找出所有的节点key
    Map<String, String> sourceMap = flat(source);
    Map<String, String> targetMap = flat(target);

    //去掉两者重复的
    sourceMap.entrySet().stream().forEach(entry -> {
      if (!targetMap.containsKey(entry.getKey())) {//source特有的属性
        result.getFromProps().add(entry.getKey());
      } else {//共有的属性
        String targetEl = targetMap.get(entry.getKey());
        if (!targetEl.equals(entry.getValue())) {
          result.getValueDiffs()
              .add(new CompareResult.ValueDiff(entry.getKey(), entry.getValue(), targetEl));
        }
      }
    });
    //target特有的属性
    targetMap.keySet().forEach(key -> {
      if (!sourceMap.containsKey(key)) {
        result.getToProps().add(key);
      }
    });

    return result;
  }

  /**
   * 摊平所有key
   *
   * @param jsonNode json
   * @return
   */
  public static Map<String, String> flat(JsonNode jsonNode) throws IOException {
    return Jsons.flat(jsonNode);
  }

}
